package com.bzy.common.util;

import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

import com.bzy.common.bean.Result;
import com.bzy.common.util.local.ExceptionUtil;
import com.bzy.common.util.local.NetworkUtil;
import com.bzy.common.util.local.ThreadLocalUtil;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import com.alibaba.fastjson.JSON;

public class HttpServletUtil {

	public static void writeResponse(ServletRequest request, ServletResponse response, Result result) throws Exception {
		String callback = request.getParameter("callback");
		String msg = JSON.toJSONString(result);
		if (StringUtil.isBlank(callback)) {
			response.getOutputStream().write(msg.getBytes("UTF-8"));
		} else {
			String jsonp = callback + "(" + msg + ")";
			response.getOutputStream().write(jsonp.getBytes("UTF-8"));
		}
	}

	@SuppressWarnings("rawtypes")
	public static String getRequestLog(HttpServletRequest request, ProceedingJoinPoint pJoinPoint,
			Boolean isAuthenticated) {

		Map<String, Object> map = new LinkedHashMap<>();

		map.put("logType", "request++++++>");

		map.put("authen", isAuthenticated);
		map.put("isAjax", HttpServletUtil.isAjax(request));

		Enumeration headerEnumeration = request.getHeaderNames();
		while (headerEnumeration.hasMoreElements()) {
			String headerName = (String) headerEnumeration.nextElement();
			map.put(headerName, request.getHeader(headerName));
		}

		map.put("remoteAddr", NetworkUtil.getRemoteAddr(request));
		if (pJoinPoint != null) {
			map.put("classMethod", pJoinPoint.getSignature().toShortString());
		}
		map.put("contextPath", request.getContextPath());
		map.put("servletPath", request.getServletPath());
		map.put("pathInfo", request.getPathInfo());

		Enumeration requestEnumeration = request.getParameterNames();
		while (requestEnumeration.hasMoreElements()) {
			String paramName = (String) requestEnumeration.nextElement();
			map.put(paramName, request.getParameter(paramName));
		}

		String requestUrl = request.getRequestURL().toString();
		String queryString = request.getQueryString();
		if (queryString == null || queryString.startsWith("_=")) {
			queryString = "";
			while (requestEnumeration.hasMoreElements()) {
				String paramName = (String) requestEnumeration.nextElement();
				queryString += paramName + "=" + request.getParameter(paramName) + "&";
			}
		}
		if (StringUtil.isNotBlank(queryString)) {
			requestUrl += "?";
			requestUrl += queryString;
		}

		map.put("requestUrl", requestUrl);
		map.put("reqSessionId", request.getRequestedSessionId());

		return JSON.toJSONString(map);
	}

	private static Result getResponseResultForLog(Object retObj) {
		Result logRet = null;
		if (retObj instanceof Result) {
			logRet = new Result();
			Result result = (Result) retObj;
			logRet.setSuccess(result.isSuccess());
			logRet.setCode(result.getCode());
			logRet.setMessage(result.getMessage());
			logRet.setTotalCount(result.getTotalCount());
			if (result.getData() != null) {
				logRet.setData("hide in log!");
			}
		}
		return logRet;
	}

	public static String getResponseLog(HttpServletRequest request, long runTime, Object retObj) {
		Map<String, Object> map = new LinkedHashMap<>();

		map.put("logType", "response======>");
		map.put("runTime", runTime);
		map.put("rspPath", request.getServletPath());
		map.put("rspSessionId", request.getRequestedSessionId());
		map.put("rspData", getResponseResultForLog(retObj));

		return JSON.toJSONString(map);
	}

	public static String getResponseContent(Object retObj) {
		String retString = "";
		Result result = getResponseResultForLog(retObj);
		if (result == null) {
			retString = JSON.toJSONString(retObj);
		} else {
			retString = JSON.toJSONString(result);
		}
		return retString;
	}

	@SuppressWarnings("rawtypes")
	public static String getRequestParam(HttpServletRequest request) {
		int reqMaxLength = 1000;
		String request_param = "";
		String queryString = request.getQueryString();
		if (StringUtils.isBlank(queryString) || queryString.startsWith("_=")) {
			Enumeration requestEnumeration = request.getParameterNames();
			while (requestEnumeration.hasMoreElements()) {
				String paramName = (String) requestEnumeration.nextElement();
				request_param += paramName + "=" + request.getParameter(paramName) + "&";
			}
		} else {
			request_param += queryString;
		}
		if (!StringUtils.isBlank(request_param)) {
			if (request_param.length() > reqMaxLength) {
				request_param = request_param.substring(0, reqMaxLength);
			}
		}
		return request_param;
	}

	public static String getAccessMode(HttpServletRequest request) {
		String access_mode = request.getParameter("access_mode");
		if (StringUtils.isBlank(access_mode)) {
			String userAgent = request.getHeader("user-agent");
			if (userAgent.contains("iPhone")) {
				access_mode = "9";
			} else if (userAgent.contains("Android")) {
				access_mode = "8";
			} else {
				access_mode = "0";
			}
		}
		return access_mode;
	}

	public static String getUmDistinctid(HttpServletRequest request) {
		String um_distinctid = "";
		Cookie[] cookie = request.getCookies();
		if (cookie != null) {
			for (int i = 0; i < cookie.length; i++) {
				Cookie cook = cookie[i];
				if (cook.getName().equalsIgnoreCase("UM_distinctid")) {
					um_distinctid = cook.getValue().toString();
					break;
				}
			}
		}
		return um_distinctid;
	}

	public static String getExceptionContent(Exception ex) {
		int exMaxLength = 1000;
		String exceptionContent = ThreadLocalUtil.getExceptionString();
		ThreadLocalUtil.setExceptionString("");
		if (StringUtils.isBlank(exceptionContent) && (ex != null)) {
			exceptionContent = ExceptionUtil.getExceptionContent(ex);
		}
		if (!StringUtils.isBlank(exceptionContent)) {
			if (exceptionContent.length() > exMaxLength) {
				exceptionContent = exceptionContent.substring(0, exMaxLength);
			}
		}
		return exceptionContent;
	}

	public static String getSessionId(HttpServletRequest request) {
		String sessionId = null;
		sessionId = request.getRequestedSessionId();
		return sessionId;
	}

	public static String getMobile(HttpServletRequest request) {
		String mobile = null;
		return mobile;
	}

	public static boolean isAjax(HttpServletRequest request) {
		return "XMLHttpRequest".equalsIgnoreCase(request.getHeader("X-Requested-With"));
	}

	public static void main(String[] args) {

	}

}
